Chapter 4

1. Slot Machines (Chapter 4 exercises, #3, p. 72)

[5 points]

Do not use grid.arrange() for this exercise. Rather, use gather() to tidy the data and then facet on window number. To make the comparison, use relative frequency bar charts (the heights of the bars in each facet sum to one). Describe how the distributions differ.

df <- gather(DAAG::vlt, key="window", value="symbol", window1:window3) 
ggplot(df) + 
  geom_bar(aes(x=symbol, y=..prop.., group=window)) + 
  facet_wrap(~window)

  1. For all three windows, the data appears to be asymmetric and skewed to the left.
  2. There’s a pattern of the first SYMBOL, 0, appearing most often in each window.
  3. There is sign of an outlier in each window, symbol 0. It’s most likely nothing. Especially in window1.
  4. There are minor gaps between shapes in each window. Number 4 doesn’t appear at all. However, I doubt that there is any particular order to the shapes; the data is nominal.

2. Detailed Mortality data (“Death2015.txt”)

[21 points]

This data comes from the “Detailed Mortality” database available on https://wonder.cdc.gov/

df <- read.csv("../data/Death2015.txt", sep="\t")
notes <- tail(df, 44)
df <- head(df, -44)

Code for all preprocessing must be shown. (That is, don’t open in the file in Excel or similar, change things around, save it, and then import to R. Why? Because your steps are not reproducible.)

  1. For Place of Death, Ten-Year Age Groups, and ICD Chapter Code variables, do the following:

Identify the type of variable (nominal, ordinal, or discrete) and draw a horizontal bar chart using best practices for order of categories.

d1.title <- ggtitle("Place of Death: Nominal Data")
d1 <- ggplot(df) + 
  geom_bar(aes(Place.of.Death)) + 
  coord_flip() +
  xlab("")
d2.title <- ggtitle("Ten Year Age Groups: Ordinal Data")
d2 <- ggplot(df) + 
  geom_bar(aes(Ten.Year.Age.Groups)) + 
  coord_flip() +
  xlab("")
d3.title <- ggtitle("ICD Chapter Code: Nominal Data")
d3 <- ggplot(df) +
  geom_bar(aes(ICD.Chapter.Code)) + 
  coord_flip() +
  xlab("")
grid.arrange(d1 + d1.title, d2 + d2.title, d3 + d3.title)

  1. Create horizontal bar charts for the ICD sub-chapter codes, one plot per ICD chapter code, by faceting on chapter code, not by using grid.arrange(). Use scales = "free" with facet_wrap(). It should look like this (with data, of course!). Describe notable features.
ggplot(df, aes(ICD.Sub.Chapter.Code)) +
  geom_bar() +
  facet_wrap(~ICD.Chapter.Code, ncol=3, scales = "free") +
  coord_flip()

  1. The Capter Code of U00-U99 only has a single Sub-Chapter, it self. As a result it is very uniform. It also doesn’t have much data.
  2. Across some charts the distribution is uneven and shows signs of little data. As a result some chapters are dominated by a single major sub chapter. For example that of H60-H93.
  3. Some charts have gaps in the data and that could be the result of too little data.
  1. Change the scales parameter to scales = "free_y". What changed? What information does this set of graphs provide that wasn’t available in part (b)?
ggplot(df, aes(ICD.Sub.Chapter.Code)) +
  geom_bar() +
  facet_wrap(~ICD.Chapter.Code, ncol=3, scales = "free_y") +
  coord_flip()

  1. Freeing “y” shows us the amount of data in each Chapter relative to other Chapters.
  2. We could now really see where there is missing data and too little data relative to each Chapter.
  1. Redraw the panels as relative frequency bar charts rather than count bar charts. (The lengths of the bars in each panel separately must sum to 1.) What new information do you gain?
ggplot(df, aes(ICD.Sub.Chapter.Code)) +
  geom_bar(aes(x=ICD.Sub.Chapter.Code, y=..prop.., group=ICD.Chapter.Code)) +
  facet_wrap(~ICD.Chapter.Code, ncol=3, scales = "free_y") +
  coord_flip()

ggplot(df, aes(ICD.Sub.Chapter.Code)) +
  geom_bar(aes(x=ICD.Sub.Chapter.Code, y=..prop.., group=ICD.Chapter.Code)) +
  facet_wrap(~ICD.Chapter.Code, ncol=3, scales = "free") +
  coord_flip()

  1. I decided to use both scales (free and free_y) to show relative frequency in the bar charts for each chapter.
  2. The gaps in the data are more evident.
  3. Some charts have multimodality and the distributions have multiple peaks.
  1. Choose one of the small panels and redraw it as a single graph, using names rather than codes. (That is, use ICD Chapter and ICD Sub-Chapter instead of the code versions.) What type of data is this? Note any interesting features.
data = subset(df, ICD.Chapter.Code %in% c("H60-H93"))
ggplot(data, aes(ICD.Sub.Chapter)) +
  geom_bar(aes(x=ICD.Sub.Chapter)) +
  xlab(unique(data$ICD.Chapter)) +
  ylab("Death Count") +
  coord_flip()

  1. This data is nominal and shows the breakdown of death for “Diseases of the ear and mastoid”.
  2. Within the death Chapter of Diseases of the ear and mastoid process we could see the distribution of deaths for each Sub Chapter.
  3. I’m mainly surprised that people die from ear infections.
  4. There’s a heavy outlier, Diseases of middle ear and mastoid. Not sure why that is. Could be because of little data.

3. Detailed Mortality, questions about the data

[6 points]

Cite your sources with links.

  1. Who is included in the death counts?
  1. When was this query processed? (Hint: it’s in the file itself; don’t provide the file time stamp.)
for(i in notes$Notes){
  if(grepl("Query Date", i)){
    print(i)
  }
}
[1] "Query Date: Feb 5, 2018 5:08:43 PM"
  • The query was processed on Feb 5, 2018 at 5:08:43 PM. (inside the data)
  1. What does “ICD” stand for? Which version is used for this particular data set? Name five other countries that use the ICD for official mortality data.
  • “ICD” stands for “International Classification Of Diseases”. (inside the data)
  • This version is Underlying Cause of Death 1999-2016, specifically 2015, for all states in U.S. (inside the data)
  • Belgium, Denmark, Canada, China, France. (https://www.cdc.gov/globalhealth/countries/default.htm)
  1. Which U.S. organizations collects mortality data? Where is the headquarters located?
  1. In brief, how is the data collected? What is the estimated accuracy rate, according to the data set documentation?

Chapter 5

1. Movie ratings

[12 points]

Explore length vs. year in the ggplot2movies data set, after removing outliers. (Choose a reasonable cutoff).

Draw four scatterplots of length vs. year from the with the following variations:

df <- subset(ggplot2movies::movies, length < 200)
  1. Points with alpha blending
ggplot(df, aes(x=length, y=year)) +
  geom_point(alpha=.1)

  1. Points with alpha blending + density estimate contour lines
ggplot(df, aes(x=length, y=year)) +
  geom_point(alpha=.1) +
  geom_density2d(bins=10)

  1. Hexagonal heatmap of bin counts
ggplot(df, aes(length, year)) +
  geom_hex(bins=30)

  1. Square heatmap of bin counts
ggplot(df, aes(length, year)) + 
  geom_bin2d(binwidth=c(10, 10)) +
  coord_equal()

For all, adjust parameters to the levels that provide the best views of the data.

  1. Describe noteworthy features of the data, using the movie ratings example on page 82 (last page of Section 5.3) as a guide.
  1. The length of films increased as years went by. 1920s saw a huge spike in the length of films.
  2. There’s a gap in the data. Very few films have the length of ~20 - 50 minutes.
  3. There’s a heavy concentration of films between the 50 minute mark and ~125 minutes.
  4. A few films, that are 150 minutes and greater, appear to be outliers. They have the same year and a higher level of length in minutes.
  5. There are no films that have a length higher then 25 minutes and were made before 1915.
  1. How do (a)-(d) compare? Are there features that you can see in some but not all of the graphs?
  1. b is more helpful in discerning the true dispersion of the data. We could see where the majority of data lies and its density and concentration.
  2. I would say c is the more difficult to read. We generally have a harder time attributing color to values. As a result, I can’t tell that there’s a gap in length between 10 min to 60 min.
  3. a communicates that there’s a gap in data. However, it is more difficult to see how the data is spread.
  4. d and c feels very similar and is difficult to read. The only thing that I could tell from these graphs is that most length is concentrated at the 100 minute.

2. Leaves (Chapter 5 exercises, #7, p. 96)

[6 points] The leaf shape dataset in the DAAG package includes three measurements on each leaf (length, width, petiole) and the logarithms of the three measurements. (a) Draw sploms for the two sets of three variables. What conclusions would you draw from each set? Which do you find more useful?

  1. Both sets of variable measurements have a positive correlation. However, it’s way easier to see a positive relationship when the log of each variable is taken.
  2. The “Leaf length, width and petiole (mm)” has more dispersion in the data and most likely a high r^2.
  3. The “Log of Leaf length, width and petiole” is log transformed and reduces skewness in the data revealing a stronger correlation.
  4. The log for each variable adjusts for outliers and makes the data more useful.
  5. Generally, if the width increases so does the the length and petiole.
df <- DAAG::leafshape
splom(df[c(1,2,3)], main = "Leaf length, width and petiole (mm)")

splom(df[c(5,6,7)], main = "Log of Leaf length, width and petiole")

  1. Redraw the sploms, colouring the cases by the variable arch, describing the type of leaf architecture. What additional structure can you see?
  1. There are two arch varieties: Plagiotropic and Orthotropic.
  2. Using log and color points we could better see that Orthotropic leaves are generally wider and longer.
  3. The Orthotropic leaf measurements are more dispersed than that of Plagiotropic leaf.
df <- DAAG::leafshape
super.sym <- trellis.par.get("superpose.symbol")
key <- list(title = "Leaf Architecture",
                 points = list(pch = super.sym$pch[1:2],
                 col = super.sym$col[1:2]),
                 text = list(c("Plagiotropic", "Orthotropic")))
splom(~df[1:3], groups=arch, data=df, panel=panel.superpose, key=key)

splom(~df[5:7], groups=arch, data=df, panel=panel.superpose, key=key)

LS0tCnRpdGxlOiAiSG9tZXdvcmsgMiIKYXV0aG9yOiBPbGVoIER1Ym5vCmRhdGU6IDAyLzA3LzE4Cm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgIGNhY2hlID0gVFJVRSkKbGlicmFyeShzY2FsZXMpCmRhdGEodmx0LCBwYWNrYWdlPSJEQUFHIikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDJtb3ZpZXMpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGxhdHRpY2UpCmBgYAoKIyMjIENoYXB0ZXIgNAoKIyMjIyAxLiBTbG90IE1hY2hpbmVzIChDaGFwdGVyIDQgZXhlcmNpc2VzLCAjMywgcC4gNzIpCgpbNSBwb2ludHNdCgpEbyBub3QgdXNlICpncmlkLmFycmFuZ2UoKSogZm9yIHRoaXMgZXhlcmNpc2UuIFJhdGhlciwgdXNlICpnYXRoZXIoKSogdG8gdGlkeSB0aGUgZGF0YSBhbmQgdGhlbiBmYWNldCBvbiB3aW5kb3cgbnVtYmVyLiAgVG8gbWFrZSB0aGUgY29tcGFyaXNvbiwgdXNlIHJlbGF0aXZlIGZyZXF1ZW5jeSBiYXIgY2hhcnRzICh0aGUgaGVpZ2h0cyBvZiB0aGUgYmFycyBpbiBlYWNoIGZhY2V0IHN1bSB0byBvbmUpLiAgRGVzY3JpYmUgaG93IHRoZSBkaXN0cmlidXRpb25zIGRpZmZlci4KCmBgYHtyLCBmaWcuaGVpZ2h0PTgsIGZpZy5sZW5ndGg9Nn0KCmRmIDwtIGdhdGhlcihEQUFHOjp2bHQsIGtleT0id2luZG93IiwgdmFsdWU9InN5bWJvbCIsIHdpbmRvdzE6d2luZG93MykgCgpnZ3Bsb3QoZGYpICsgCiAgZ2VvbV9iYXIoYWVzKHg9c3ltYm9sLCB5PS4ucHJvcC4uLCBncm91cD13aW5kb3cpKSArIAogIGZhY2V0X3dyYXAofndpbmRvdykKYGBgCjEuIEZvciBhbGwgdGhyZWUgd2luZG93cywgdGhlIGRhdGEgYXBwZWFycyB0byBiZSBhc3ltbWV0cmljIGFuZCBza2V3ZWQgdG8gdGhlIGxlZnQuCjIuIFRoZXJlJ3MgYSBwYXR0ZXJuIG9mIHRoZSBmaXJzdCBTWU1CT0wsIGAwYCwgYXBwZWFyaW5nIG1vc3Qgb2Z0ZW4gaW4gZWFjaCB3aW5kb3cuIAozLiBUaGVyZSBpcyBzaWduIG9mIGFuIG91dGxpZXIgaW4gZWFjaCB3aW5kb3csIGBzeW1ib2wgMGAuIEl0J3MgbW9zdCBsaWtlbHkgbm90aGluZy4gRXNwZWNpYWxseSBpbiBgd2luZG93MWAuCjQuIFRoZXJlIGFyZSBtaW5vciBnYXBzIGJldHdlZW4gc2hhcGVzIGluIGVhY2ggd2luZG93LiBOdW1iZXIgNCBkb2Vzbid0IGFwcGVhciBhdCBhbGwuIEhvd2V2ZXIsIEkgZG91YnQgdGhhdCB0aGVyZSBpcyBhbnkgcGFydGljdWxhciBvcmRlciB0byB0aGUgc2hhcGVzOyB0aGUgZGF0YSBpcyBub21pbmFsLgoKIyMjIyAyLiBEZXRhaWxlZCBNb3J0YWxpdHkgZGF0YSAoIkRlYXRoMjAxNS50eHQiKQoKWzIxIHBvaW50c10KClRoaXMgZGF0YSBjb21lcyBmcm9tIHRoZSAiRGV0YWlsZWQgTW9ydGFsaXR5IiBkYXRhYmFzZSBhdmFpbGFibGUgb24gaHR0cHM6Ly93b25kZXIuY2RjLmdvdi8KYGBge3J9CmRmIDwtIHJlYWQuY3N2KCIuLi9kYXRhL0RlYXRoMjAxNS50eHQiLCBzZXA9Ilx0IikKbm90ZXMgPC0gdGFpbChkZiwgNDQpCmRmIDwtIGhlYWQoZGYsIC00NCkKYGBgCgpDb2RlIGZvciBhbGwgcHJlcHJvY2Vzc2luZyBtdXN0IGJlIHNob3duLiAoVGhhdCBpcywgZG9uJ3Qgb3BlbiBpbiB0aGUgZmlsZSBpbiBFeGNlbCBvciBzaW1pbGFyLCBjaGFuZ2UgdGhpbmdzIGFyb3VuZCwgc2F2ZSBpdCwgYW5kIHRoZW4gaW1wb3J0IHRvIFIuIFdoeT8gQmVjYXVzZSB5b3VyIHN0ZXBzIGFyZSBub3QgcmVwcm9kdWNpYmxlLikKCihhKSBGb3IgYFBsYWNlIG9mIERlYXRoYCwgYFRlbi1ZZWFyIEFnZSBHcm91cHNgLCBhbmQgYElDRCBDaGFwdGVyIENvZGVgIHZhcmlhYmxlcywgZG8gdGhlIGZvbGxvd2luZzoKCklkZW50aWZ5IHRoZSB0eXBlIG9mIHZhcmlhYmxlIChub21pbmFsLCBvcmRpbmFsLCBvciBkaXNjcmV0ZSkgYW5kIGRyYXcgYSBob3Jpem9udGFsIGJhciBjaGFydCB1c2luZyBiZXN0IHByYWN0aWNlcyBmb3Igb3JkZXIgb2YgY2F0ZWdvcmllcy4KCmBgYHtyLCBmaWcuaGVpZ2h0PTE2LCBmaWcud2lkdGg9MTB9CmQxLnRpdGxlIDwtIGdndGl0bGUoIlBsYWNlIG9mIERlYXRoOiBOb21pbmFsIERhdGEiKQpkMSA8LSBnZ3Bsb3QoZGYpICsgCiAgZ2VvbV9iYXIoYWVzKFBsYWNlLm9mLkRlYXRoKSkgKyAKICBjb29yZF9mbGlwKCkgKwogIHhsYWIoIiIpCmQyLnRpdGxlIDwtIGdndGl0bGUoIlRlbiBZZWFyIEFnZSBHcm91cHM6IE9yZGluYWwgRGF0YSIpCmQyIDwtIGdncGxvdChkZikgKyAKICBnZW9tX2JhcihhZXMoVGVuLlllYXIuQWdlLkdyb3VwcykpICsgCiAgY29vcmRfZmxpcCgpICsKICB4bGFiKCIiKQpkMy50aXRsZSA8LSBnZ3RpdGxlKCJJQ0QgQ2hhcHRlciBDb2RlOiBOb21pbmFsIERhdGEiKQpkMyA8LSBnZ3Bsb3QoZGYpICsKICBnZW9tX2JhcihhZXMoSUNELkNoYXB0ZXIuQ29kZSkpICsgCiAgY29vcmRfZmxpcCgpICsKICB4bGFiKCIiKQoKZ3JpZC5hcnJhbmdlKGQxICsgZDEudGl0bGUsIGQyICsgZDIudGl0bGUsIGQzICsgZDMudGl0bGUpCmBgYAoKCihiKSBDcmVhdGUgaG9yaXpvbnRhbCBiYXIgY2hhcnRzIGZvciB0aGUgSUNEIHN1Yi1jaGFwdGVyIGNvZGVzLCBvbmUgcGxvdCBwZXIgSUNEIGNoYXB0ZXIgY29kZSwgYnkgZmFjZXRpbmcgb24gY2hhcHRlciBjb2RlLCAqbm90KiBieSB1c2luZyAqZ3JpZC5hcnJhbmdlKCkqLiAgVXNlIGBzY2FsZXMgPSAiZnJlZSJgIHdpdGggYGZhY2V0X3dyYXAoKWAuIEl0IHNob3VsZCBsb29rIGxpa2UgdGhpcyAod2l0aCBkYXRhLCBvZiBjb3Vyc2UhKS4gRGVzY3JpYmUgbm90YWJsZSBmZWF0dXJlcy4KCmBgYHtyLCBmaWcuaGVpZ2h0PTIwLCBmaWcud2lkdGg9MTB9CmdncGxvdChkZiwgYWVzKElDRC5TdWIuQ2hhcHRlci5Db2RlKSkgKwogIGdlb21fYmFyKCkgKwogIGZhY2V0X3dyYXAofklDRC5DaGFwdGVyLkNvZGUsIG5jb2w9Mywgc2NhbGVzID0gImZyZWUiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoxLiBUaGUgQ2FwdGVyIENvZGUgb2YgYFUwMC1VOTlgIG9ubHkgaGFzIGEgc2luZ2xlIFN1Yi1DaGFwdGVyLCBpdCBzZWxmLiBBcyBhIHJlc3VsdCBpdCBpcyB2ZXJ5IHVuaWZvcm0uIEl0IGFsc28gZG9lc24ndCBoYXZlIG11Y2ggZGF0YS4KMi4gQWNyb3NzIHNvbWUgY2hhcnRzIHRoZSBkaXN0cmlidXRpb24gaXMgdW5ldmVuIGFuZCBzaG93cyBzaWducyBvZiBsaXR0bGUgZGF0YS4gQXMgYSByZXN1bHQgc29tZSBjaGFwdGVycyBhcmUgZG9taW5hdGVkIGJ5IGEgc2luZ2xlIG1ham9yIHN1YiBjaGFwdGVyLiBGb3IgZXhhbXBsZSB0aGF0IG9mIGBINjAtSDkzYC4gCjMuIFNvbWUgY2hhcnRzIGhhdmUgZ2FwcyBpbiB0aGUgZGF0YSBhbmQgdGhhdCBjb3VsZCBiZSB0aGUgcmVzdWx0IG9mIHRvbyBsaXR0bGUgZGF0YS4KCihjKSBDaGFuZ2UgdGhlIGBzY2FsZXNgIHBhcmFtZXRlciB0byBgc2NhbGVzID0gImZyZWVfeSJgLiBXaGF0IGNoYW5nZWQ/ICBXaGF0IGluZm9ybWF0aW9uIGRvZXMgdGhpcyBzZXQgb2YgZ3JhcGhzIHByb3ZpZGUgdGhhdCB3YXNuJ3QgYXZhaWxhYmxlIGluIHBhcnQgKGIpPwpgYGB7ciwgZmlnLmhlaWdodD0yMCwgZmlnLndpZHRoPTEwfQpnZ3Bsb3QoZGYsIGFlcyhJQ0QuU3ViLkNoYXB0ZXIuQ29kZSkpICsKICBnZW9tX2JhcigpICsKICBmYWNldF93cmFwKH5JQ0QuQ2hhcHRlci5Db2RlLCBuY29sPTMsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoxLiBGcmVlaW5nICJ5IiBzaG93cyB1cyB0aGUgYW1vdW50IG9mIGRhdGEgaW4gZWFjaCBDaGFwdGVyIHJlbGF0aXZlIHRvIG90aGVyIENoYXB0ZXJzLgoyLiBXZSBjb3VsZCBub3cgcmVhbGx5IHNlZSB3aGVyZSB0aGVyZSBpcyBtaXNzaW5nIGRhdGEgYW5kIHRvbyBsaXR0bGUgZGF0YSByZWxhdGl2ZSB0byBlYWNoIENoYXB0ZXIuCgooZCkgUmVkcmF3IHRoZSBwYW5lbHMgYXMgKnJlbGF0aXZlIGZyZXF1ZW5jeSogYmFyIGNoYXJ0cyByYXRoZXIgdGhhbiAqY291bnQqIGJhciBjaGFydHMuIChUaGUgbGVuZ3RocyBvZiB0aGUgYmFycyAqaW4gZWFjaCBwYW5lbCBzZXBhcmF0ZWx5KiBtdXN0IHN1bSB0byAxLikgV2hhdCBuZXcgaW5mb3JtYXRpb24gZG8geW91IGdhaW4/CmBgYHtyLCBmaWcuaGVpZ2h0PTIwLCBmaWcud2lkdGg9MTB9CmdncGxvdChkZiwgYWVzKElDRC5TdWIuQ2hhcHRlci5Db2RlKSkgKwogIGdlb21fYmFyKGFlcyh4PUlDRC5TdWIuQ2hhcHRlci5Db2RlLCB5PS4ucHJvcC4uLCBncm91cD1JQ0QuQ2hhcHRlci5Db2RlKSkgKwogIGZhY2V0X3dyYXAofklDRC5DaGFwdGVyLkNvZGUsIG5jb2w9Mywgc2NhbGVzID0gImZyZWVfeSIpICsKICBjb29yZF9mbGlwKCkKZ2dwbG90KGRmLCBhZXMoSUNELlN1Yi5DaGFwdGVyLkNvZGUpKSArCiAgZ2VvbV9iYXIoYWVzKHg9SUNELlN1Yi5DaGFwdGVyLkNvZGUsIHk9Li5wcm9wLi4sIGdyb3VwPUlDRC5DaGFwdGVyLkNvZGUpKSArCiAgZmFjZXRfd3JhcCh+SUNELkNoYXB0ZXIuQ29kZSwgbmNvbD0zLCBzY2FsZXMgPSAiZnJlZSIpICsKICBjb29yZF9mbGlwKCkKYGBgIAoxLiBJIGRlY2lkZWQgdG8gdXNlIGJvdGggc2NhbGVzIChgZnJlZWAgYW5kIGBmcmVlX3lgKSB0byBzaG93IHJlbGF0aXZlIGZyZXF1ZW5jeSBpbiB0aGUgYmFyIGNoYXJ0cyBmb3IgZWFjaCBjaGFwdGVyLgoyLiBUaGUgZ2FwcyBpbiB0aGUgZGF0YSBhcmUgbW9yZSBldmlkZW50LgozLiBTb21lIGNoYXJ0cyBoYXZlIG11bHRpbW9kYWxpdHkgYW5kIHRoZSBkaXN0cmlidXRpb25zIGhhdmUgbXVsdGlwbGUgcGVha3MuCgooZSkgQ2hvb3NlIG9uZSBvZiB0aGUgc21hbGwgcGFuZWxzIGFuZCByZWRyYXcgaXQgYXMgYSBzaW5nbGUgZ3JhcGgsIHVzaW5nIG5hbWVzIHJhdGhlciB0aGFuIGNvZGVzLiAoVGhhdCBpcywgdXNlIGBJQ0QgQ2hhcHRlcmAgYW5kIGBJQ0QgU3ViLUNoYXB0ZXJgIGluc3RlYWQgb2YgdGhlIGNvZGUgdmVyc2lvbnMuKSAgV2hhdCB0eXBlIG9mIGRhdGEgaXMgdGhpcz8gTm90ZSBhbnkgaW50ZXJlc3RpbmcgZmVhdHVyZXMuCgpgYGB7ciwgZmlnLmhlaWdodD04LCBmaWcubGVuZ3RoPTZ9CmRhdGEgPSBzdWJzZXQoZGYsIElDRC5DaGFwdGVyLkNvZGUgJWluJSBjKCJINjAtSDkzIikpCmdncGxvdChkYXRhLCBhZXMoSUNELlN1Yi5DaGFwdGVyKSkgKwogIGdlb21fYmFyKGFlcyh4PUlDRC5TdWIuQ2hhcHRlcikpICsKICB4bGFiKHVuaXF1ZShkYXRhJElDRC5DaGFwdGVyKSkgKwogIHlsYWIoIkRlYXRoIENvdW50IikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKMS4gVGhpcyBkYXRhIGlzIG5vbWluYWwgYW5kIHNob3dzIHRoZSBicmVha2Rvd24gb2YgZGVhdGggZm9yICJEaXNlYXNlcyBvZiB0aGUgZWFyIGFuZCBtYXN0b2lkIi4KMi4gV2l0aGluIHRoZSBkZWF0aCBDaGFwdGVyIG9mIGBEaXNlYXNlcyBvZiB0aGUgZWFyIGFuZCBtYXN0b2lkIHByb2Nlc3NgIHdlIGNvdWxkIHNlZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGRlYXRocyBmb3IgZWFjaCBTdWIgQ2hhcHRlci4gCjMuIEknbSBtYWlubHkgc3VycHJpc2VkIHRoYXQgcGVvcGxlIGRpZSBmcm9tIGVhciBpbmZlY3Rpb25zLiAKNC4gVGhlcmUncyBhIGhlYXZ5IG91dGxpZXIsIGBEaXNlYXNlcyBvZiBtaWRkbGUgZWFyIGFuZCBtYXN0b2lkYC4gTm90IHN1cmUgd2h5IHRoYXQgaXMuIENvdWxkIGJlIGJlY2F1c2Ugb2YgbGl0dGxlIGRhdGEuCgojIyMjIDMuIERldGFpbGVkIE1vcnRhbGl0eSwgcXVlc3Rpb25zIGFib3V0IHRoZSBkYXRhCgpbNiBwb2ludHNdCgpDaXRlIHlvdXIgc291cmNlcyB3aXRoIGxpbmtzLiAKCihhKSBXaG8gaXMgaW5jbHVkZWQgaW4gdGhlIGRlYXRoIGNvdW50cz8KLSBVLlMuIGNpdmlsaWFucywgRmVtYWxlIGFuZCBNYWxlCi0gTm9uIGluc3RpdHV0aW9uYWxpemVkIHBvcHVsYXRpb24KLSBBZ2UgPDEgLSA4NSsKLSBBbGwgb3JpZ2lucwooaHR0cHM6Ly93b25kZXIuY2RjLmdvdi9jb250cm9sbGVyL2RhdGFyZXF1ZXN0L0Q3NikKCihiKSBXaGVuIHdhcyB0aGlzIHF1ZXJ5IHByb2Nlc3NlZD8gIChIaW50OiBpdCdzIGluIHRoZSBmaWxlIGl0c2VsZjsgZG9uJ3QgcHJvdmlkZSB0aGUgZmlsZSB0aW1lIHN0YW1wLikKYGBge3J9CmZvcihpIGluIG5vdGVzJE5vdGVzKXsKICBpZihncmVwbCgiUXVlcnkgRGF0ZSIsIGkpKXsKICAgIHByaW50KGkpCiAgfQp9CmBgYAotIFRoZSBxdWVyeSB3YXMgcHJvY2Vzc2VkIG9uIEZlYiA1LCAyMDE4IGF0IDU6MDg6NDMgUE0uIChpbnNpZGUgdGhlIGRhdGEpCgooYykgV2hhdCBkb2VzICJJQ0QiIHN0YW5kIGZvcj8gV2hpY2ggdmVyc2lvbiBpcyB1c2VkIGZvciB0aGlzIHBhcnRpY3VsYXIgZGF0YSBzZXQ/IE5hbWUgZml2ZSBvdGhlciBjb3VudHJpZXMgdGhhdCB1c2UgdGhlIElDRCBmb3Igb2ZmaWNpYWwgbW9ydGFsaXR5IGRhdGEuCi0gIklDRCIgc3RhbmRzIGZvciAiSW50ZXJuYXRpb25hbCBDbGFzc2lmaWNhdGlvbiBPZiBEaXNlYXNlcyIuIChpbnNpZGUgdGhlIGRhdGEpCi0gVGhpcyB2ZXJzaW9uIGlzIGBVbmRlcmx5aW5nIENhdXNlIG9mIERlYXRoIDE5OTktMjAxNmAsIHNwZWNpZmljYWxseSAyMDE1LCBmb3IgYWxsIHN0YXRlcyBpbiBVLlMuIChpbnNpZGUgdGhlIGRhdGEpCi0gQmVsZ2l1bSwgRGVubWFyaywgQ2FuYWRhLCBDaGluYSwgRnJhbmNlLiAoaHR0cHM6Ly93d3cuY2RjLmdvdi9nbG9iYWxoZWFsdGgvY291bnRyaWVzL2RlZmF1bHQuaHRtKQoKKGQpIFdoaWNoIFUuUy4gb3JnYW5pemF0aW9ucyBjb2xsZWN0cyBtb3J0YWxpdHkgZGF0YT8gV2hlcmUgaXMgdGhlIGhlYWRxdWFydGVycyBsb2NhdGVkPwotIE5DSFMgT3JnYW5pemF0aW9uIChodHRwczovL3d3dy5jZGMuZ292L25jaHMvYWJvdXQvaW5kZXguaHRtKQotIEhlYWRxdWFydGVycwlIeWF0dHN2aWxsZSwgTUQgKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL05hdGlvbmFsX0NlbnRlcl9mb3JfSGVhbHRoX1N0YXRpc3RpY3MpCgooZSkgSW4gYnJpZWYsIGhvdyBpcyB0aGUgZGF0YSBjb2xsZWN0ZWQ/ICBXaGF0IGlzIHRoZSBlc3RpbWF0ZWQgYWNjdXJhY3kgcmF0ZSwgYWNjb3JkaW5nIHRvIHRoZSBkYXRhIHNldCBkb2N1bWVudGF0aW9uPwotIERhdGEgaXMgY29sbGVjdGVkIHZpYSBzdXJ2ZXlzLCBwZXJzb25hbCBpbnRlcnZpZXdzIGluIGhvdXNlaG9sZHMsIGJ5IHBob25lLCBmcm9tIG90aGVyIGFnZW5jaWVzIGFuZCBwcml2YXRlIHBhcnRuZXJzLiBUaGVyZSBhcmUgNCBtYWluIGNoYW5uZWxzIHRocm91Z2ggd2hpY2ggTkNIUyBjb2xsZWN0cyBkYXRhOiBgTmF0aW9uYWwgVml0YWwgU3RhdGlzdGljcyBTeXN0ZW1gLCBgTmF0aW9uYWwgSGVhbHRoIEludGVydmlldyBTdXJ2ZXlgLCBgTmF0aW9uYWwgSGVhbHRoIGFuZCBOdXRyaXRpb24gRXhhbWluYXRpb24gU3VydmV5YCwgYE5hdGlvbmFsIEhlYWx0aCBDYXJlIFN1cnZleXNgLiAod2lraXBlZGlhIGFuZCBodHRwczovL3d3dy5jZGMuZ292L25jaHMvZGF0YS9mYWN0c2hlZXRzL2ZhY3RzaGVldF9oZWFsdGhfc3RhdGlzdGljcy5odG0pCi0gVGhlIE5DSFMgbWFpbmx5IGdvZXMgb3ZlciB0aGVpciBkYXRhIGdhdGhlcmluZyBwcm9jZXNzLCBidXQgbmV2ZXIgdG91Y2hlcyBvbiB0aGUgZXN0aW1hdGVkIGFjY3VyYWN5IHJhdGUuIEkgd291bGQgc2F5IGl0J3MgcHJldHR5IGhpZ2ggYWNjb3JkaW5nIHRvIHRoZWlyIGRvY3VtZW50YXRpb24uIChodHRwczovL3d3dy5jZGMuZ292L25jaHMvZGF0YS9mYWN0c2hlZXRzL2ZhY3RzaGVldF9uaGlzLmh0bSkKCiMjIyBDaGFwdGVyIDUKCiMjIyMgMS4gTW92aWUgcmF0aW5ncwoKWzEyIHBvaW50c10KCkV4cGxvcmUgKmxlbmd0aCogdnMuICp5ZWFyKiBpbiB0aGUgKipnZ3Bsb3QybW92aWVzKiogZGF0YSBzZXQsIGFmdGVyIHJlbW92aW5nIG91dGxpZXJzLiAoQ2hvb3NlIGEgcmVhc29uYWJsZSBjdXRvZmYpLgoKRHJhdyBmb3VyIHNjYXR0ZXJwbG90cyBvZiAqbGVuZ3RoKiB2cy4gKnllYXIqIGZyb20gdGhlIHdpdGggdGhlIGZvbGxvd2luZyB2YXJpYXRpb25zOgoKYGBge3J9CmRmIDwtIHN1YnNldChnZ3Bsb3QybW92aWVzOjptb3ZpZXMsIGxlbmd0aCA8IDIwMCkKYGBgCgooYSkgUG9pbnRzIHdpdGggYWxwaGEgYmxlbmRpbmcKYGBge3IsIGZpZy5oZWlnaHQ9OCwgZmlnLmxlbmd0aD02fQpnZ3Bsb3QoZGYsIGFlcyh4PWxlbmd0aCwgeT15ZWFyKSkgKwogIGdlb21fcG9pbnQoYWxwaGE9LjEpCmBgYAooYikgUG9pbnRzIHdpdGggYWxwaGEgYmxlbmRpbmcgKyBkZW5zaXR5IGVzdGltYXRlIGNvbnRvdXIgbGluZXMKYGBge3IsIGZpZy5oZWlnaHQ9OCwgZmlnLmxlbmd0aD02fQpnZ3Bsb3QoZGYsIGFlcyh4PWxlbmd0aCwgeT15ZWFyKSkgKwogIGdlb21fcG9pbnQoYWxwaGE9LjEpICsKICBnZW9tX2RlbnNpdHkyZChiaW5zPTEwKQpgYGAKKGMpIEhleGFnb25hbCBoZWF0bWFwIG9mIGJpbiBjb3VudHMKYGBge3IsIGZpZy5oZWlnaHQ9OCwgZmlnLmxlbmd0aD02fQpnZ3Bsb3QoZGYsIGFlcyhsZW5ndGgsIHllYXIpKSArCiAgZ2VvbV9oZXgoYmlucz0zMCkKYGBgCihkKSBTcXVhcmUgaGVhdG1hcCBvZiBiaW4gY291bnRzIApgYGB7ciwgZmlnLmhlaWdodD04LCBmaWcubGVuZ3RoPTZ9CmdncGxvdChkZiwgYWVzKGxlbmd0aCwgeWVhcikpICsgCiAgZ2VvbV9iaW4yZChiaW53aWR0aD1jKDEwLCAxMCkpICsKICBjb29yZF9lcXVhbCgpCmBgYAoKRm9yIGFsbCwgYWRqdXN0IHBhcmFtZXRlcnMgdG8gdGhlIGxldmVscyB0aGF0IHByb3ZpZGUgdGhlIGJlc3Qgdmlld3Mgb2YgdGhlIGRhdGEuCgooZSkgRGVzY3JpYmUgbm90ZXdvcnRoeSBmZWF0dXJlcyBvZiB0aGUgZGF0YSwgdXNpbmcgdGhlIG1vdmllIHJhdGluZ3MgZXhhbXBsZSBvbiBwYWdlIDgyIChsYXN0IHBhZ2Ugb2YgU2VjdGlvbiA1LjMpIGFzIGEgZ3VpZGUuICAKMS4gVGhlIGxlbmd0aCBvZiBmaWxtcyBpbmNyZWFzZWQgYXMgeWVhcnMgd2VudCBieS4gMTkyMHMgc2F3IGEgaHVnZSBzcGlrZSBpbiB0aGUgbGVuZ3RoIG9mIGZpbG1zLiAgCjIuIFRoZXJlJ3MgYSBnYXAgaW4gdGhlIGRhdGEuIFZlcnkgZmV3IGZpbG1zIGhhdmUgdGhlIGxlbmd0aCBvZiB+MjAgLSA1MCBtaW51dGVzLgozLiBUaGVyZSdzIGEgaGVhdnkgY29uY2VudHJhdGlvbiBvZiBmaWxtcyBiZXR3ZWVuIHRoZSA1MCBtaW51dGUgbWFyayBhbmQgfjEyNSBtaW51dGVzLgo0LiBBIGZldyBmaWxtcywgdGhhdCBhcmUgMTUwIG1pbnV0ZXMgYW5kIGdyZWF0ZXIsIGFwcGVhciB0byBiZSBvdXRsaWVycy4gVGhleSBoYXZlIHRoZSBzYW1lIHllYXIgYW5kIGEgaGlnaGVyIGxldmVsIG9mIGxlbmd0aCBpbiBtaW51dGVzLgo1LiBUaGVyZSBhcmUgbm8gZmlsbXMgdGhhdCBoYXZlIGEgbGVuZ3RoIGhpZ2hlciB0aGVuIDI1IG1pbnV0ZXMgYW5kIHdlcmUgbWFkZSBiZWZvcmUgMTkxNS4KCihmKSBIb3cgZG8gKGEpLShkKSBjb21wYXJlPyBBcmUgdGhlcmUgZmVhdHVyZXMgdGhhdCB5b3UgY2FuIHNlZSBpbiBzb21lIGJ1dCBub3QgYWxsIG9mIHRoZSBncmFwaHM/CjEuIGBiYCBpcyBtb3JlIGhlbHBmdWwgaW4gZGlzY2VybmluZyB0aGUgdHJ1ZSBkaXNwZXJzaW9uIG9mIHRoZSBkYXRhLiBXZSBjb3VsZCBzZWUgd2hlcmUgdGhlIG1ham9yaXR5IG9mIGRhdGEgbGllcyBhbmQgaXRzIGRlbnNpdHkgYW5kIGNvbmNlbnRyYXRpb24uIAoyLiBJIHdvdWxkIHNheSBgY2AgaXMgdGhlIG1vcmUgZGlmZmljdWx0IHRvIHJlYWQuIFdlIGdlbmVyYWxseSBoYXZlIGEgaGFyZGVyIHRpbWUgYXR0cmlidXRpbmcgY29sb3IgdG8gdmFsdWVzLiBBcyBhIHJlc3VsdCwgSSBjYW4ndCB0ZWxsIHRoYXQgdGhlcmUncyBhIGdhcCBpbiBsZW5ndGggYmV0d2VlbiAxMCBtaW4gdG8gNjAgbWluLgozLiBgYWAgY29tbXVuaWNhdGVzIHRoYXQgdGhlcmUncyBhIGdhcCBpbiBkYXRhLiBIb3dldmVyLCBpdCBpcyBtb3JlIGRpZmZpY3VsdCB0byBzZWUgaG93IHRoZSBkYXRhIGlzIHNwcmVhZC4KNC4gYGRgIGFuZCBgY2AgZmVlbHMgdmVyeSBzaW1pbGFyIGFuZCBpcyBkaWZmaWN1bHQgdG8gcmVhZC4gVGhlIG9ubHkgdGhpbmcgdGhhdCBJIGNvdWxkIHRlbGwgZnJvbSB0aGVzZSBncmFwaHMgaXMgdGhhdCBtb3N0IGxlbmd0aCBpcyBjb25jZW50cmF0ZWQgYXQgdGhlIDEwMCBtaW51dGUuCgojIyMjIDIuIExlYXZlcyAoQ2hhcHRlciA1IGV4ZXJjaXNlcywgIzcsIHAuIDk2KQpbNiBwb2ludHNdClRoZSBsZWFmIHNoYXBlIGRhdGFzZXQgaW4gdGhlIERBQUcgcGFja2FnZSBpbmNsdWRlcyB0aHJlZSBtZWFzdXJlbWVudHMgb24gZWFjaCBsZWFmIChsZW5ndGgsIHdpZHRoLCBwZXRpb2xlKSBhbmQgdGhlIGxvZ2FyaXRobXMgb2YgdGhlIHRocmVlIG1lYXN1cmVtZW50cy4KKGEpIERyYXcgc3Bsb21zIGZvciB0aGUgdHdvIHNldHMgb2YgdGhyZWUgdmFyaWFibGVzLiBXaGF0IGNvbmNsdXNpb25zIHdvdWxkIHlvdSBkcmF3IGZyb20gZWFjaCBzZXQ/IFdoaWNoIGRvIHlvdSBmaW5kIG1vcmUgdXNlZnVsPwoKMS4gQm90aCBzZXRzIG9mIHZhcmlhYmxlIG1lYXN1cmVtZW50cyBoYXZlIGEgcG9zaXRpdmUgY29ycmVsYXRpb24uIEhvd2V2ZXIsIGl0J3Mgd2F5IGVhc2llciB0byBzZWUgYSBwb3NpdGl2ZSByZWxhdGlvbnNoaXAgd2hlbiB0aGUgbG9nIG9mIGVhY2ggdmFyaWFibGUgaXMgdGFrZW4uCjIuIFRoZSAiTGVhZiBsZW5ndGgsIHdpZHRoIGFuZCBwZXRpb2xlIChtbSkiIGhhcyBtb3JlIGRpc3BlcnNpb24gaW4gdGhlIGRhdGEgYW5kIG1vc3QgbGlrZWx5IGEgaGlnaCByXjIuCjMuIFRoZSAiTG9nIG9mIExlYWYgbGVuZ3RoLCB3aWR0aCBhbmQgcGV0aW9sZSIgaXMgbG9nIHRyYW5zZm9ybWVkIGFuZCByZWR1Y2VzIHNrZXduZXNzIGluIHRoZSBkYXRhIHJldmVhbGluZyBhIHN0cm9uZ2VyIGNvcnJlbGF0aW9uLiAKNC4gVGhlIGxvZyBmb3IgZWFjaCB2YXJpYWJsZSBhZGp1c3RzIGZvciBvdXRsaWVycyBhbmQgbWFrZXMgdGhlIGRhdGEgbW9yZSB1c2VmdWwuCjUuIEdlbmVyYWxseSwgaWYgdGhlIHdpZHRoIGluY3JlYXNlcyBzbyBkb2VzIHRoZSB0aGUgbGVuZ3RoIGFuZCBwZXRpb2xlLgpgYGB7ciwgZmlnLmhlaWdodD04LCBmaWcubGVuZ3RoPTV9CmRmIDwtIERBQUc6OmxlYWZzaGFwZQpzcGxvbShkZltjKDEsMiwzKV0sIG1haW4gPSAiTGVhZiBsZW5ndGgsIHdpZHRoIGFuZCBwZXRpb2xlIChtbSkiKQpzcGxvbShkZltjKDUsNiw3KV0sIG1haW4gPSAiTG9nIG9mIExlYWYgbGVuZ3RoLCB3aWR0aCBhbmQgcGV0aW9sZSIpCmBgYAoKKGIpIFJlZHJhdyB0aGUgc3Bsb21zLCBjb2xvdXJpbmcgdGhlIGNhc2VzIGJ5IHRoZSB2YXJpYWJsZSBhcmNoLCBkZXNjcmliaW5nIHRoZSB0eXBlIG9mIGxlYWYgYXJjaGl0ZWN0dXJlLiBXaGF0IGFkZGl0aW9uYWwgc3RydWN0dXJlIGNhbiB5b3Ugc2VlPwoxLiBUaGVyZSBhcmUgdHdvIGFyY2ggdmFyaWV0aWVzOiBQbGFnaW90cm9waWMgYW5kIE9ydGhvdHJvcGljLgoyLiBVc2luZyBsb2cgYW5kIGNvbG9yIHBvaW50cyB3ZSBjb3VsZCBiZXR0ZXIgc2VlIHRoYXQgT3J0aG90cm9waWMgbGVhdmVzIGFyZSBnZW5lcmFsbHkgd2lkZXIgYW5kIGxvbmdlci4KMy4gVGhlIE9ydGhvdHJvcGljIGxlYWYgbWVhc3VyZW1lbnRzIGFyZSBtb3JlIGRpc3BlcnNlZCB0aGFuIHRoYXQgb2YgUGxhZ2lvdHJvcGljIGxlYWYuIAoKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy5sZW5ndGg9OH0KZGYgPC0gREFBRzo6bGVhZnNoYXBlCnN1cGVyLnN5bSA8LSB0cmVsbGlzLnBhci5nZXQoInN1cGVycG9zZS5zeW1ib2wiKQoKa2V5IDwtIGxpc3QodGl0bGUgPSAiTGVhZiBBcmNoaXRlY3R1cmUiLAogICAgICAgICAgICAgICAgIHBvaW50cyA9IGxpc3QocGNoID0gc3VwZXIuc3ltJHBjaFsxOjJdLAogICAgICAgICAgICAgICAgIGNvbCA9IHN1cGVyLnN5bSRjb2xbMToyXSksCiAgICAgICAgICAgICAgICAgdGV4dCA9IGxpc3QoYygiUGxhZ2lvdHJvcGljIiwgIk9ydGhvdHJvcGljIikpKQoKc3Bsb20ofmRmWzE6M10sIGdyb3Vwcz1hcmNoLCBkYXRhPWRmLCBwYW5lbD1wYW5lbC5zdXBlcnBvc2UsIGtleT1rZXkpCnNwbG9tKH5kZls1OjddLCBncm91cHM9YXJjaCwgZGF0YT1kZiwgcGFuZWw9cGFuZWwuc3VwZXJwb3NlLCBrZXk9a2V5KQpgYGA=